<?php

namespace App\Http\Controllers\Api\v1;

use App\Http\Controllers\Controller;
use App\Http\FormValidator\Api\v1\PassportLoginWxMini;
use App\Http\FormValidator\Api\v1\PassportLoginWxMiniPhone;
use App\Http\Request\Api\v1\Passport\LoginRequest;
use App\Http\Request\Api\v1\Passport\LoginWxPhoneRequest;
use App\Http\Request\Api\v1\Passport\MobileLoginRequest;
use App\Http\Request\Api\v1\Passport\MobileRegisterRequest;
use App\Http\Request\Api\v1\Passport\RegisterRequest;
use App\Http\Request\Api\v1\Passport\ThirdLoginRequest;
use App\Master\Enum\RedisKeyEnum;
use App\Master\Framework\Library\Wechat\MiniAppLibrary;
use App\Models\Arts\SmsCodeModel;
use App\Models\Arts\UserModel;
use App\Models\Arts\UserThirdModel;
use App\Services\Easywechat\MiniAppService;
use App\Utils\AppResult;
use App\Utils\Encrypt\Token;
use App\Utils\RedisUtil;

/**
 * 通行证示例
 * Author:panda
 * Email:joeyoung0314@qq.com
 * Class PassportController
 * @package App\Http\Controllers\Api\v1
 */
class PassportController extends Controller
{
    // 日志模块名称
    const LOG_MODULE = 'v1/PassportController';

    /**
     * 账号登录
     * @param LoginRequest $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function login(LoginRequest $request)
    {
        // 参数接管
        $params = $request->validated();

        $userModel = new UserModel();
        if (!$userModel->login($params['account'], $params['password'])) {
            return AppResult::response201($userModel->getMessage());
        }
        $user = $userModel->getData();
        // 更新登录时间
        UserModel::loginTime($user['id']);

        $token = Token::create(['user_id' => $user['id']]);

        return AppResult::response200('登录成功！', [
            'token' => $token
        ]);
    }

    /**
     * 账号注册
     * @param RegisterRequest $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function register(RegisterRequest $request)
    {
        // 参数接管
        $params = $request->validated();

        $userModel = new UserModel();
        if ($userModel->getByAccount($params['account'])) {
            return AppResult::response201('账号已注册！');
        }

        if (!$userModel->register(account: $params['account'], password: $params['password'], extend: $params)) {
            return AppResult::response201('注册失败');
        }
        $user = $userModel->getData();

        // 更新登录时间
        UserModel::loginTime($user['id']);

        $token = Token::create(['user_id' => $user['id']]);

        return AppResult::response200('注册成功！', [
            'token' => $token
        ]);
    }

    /**
     * 手机号登录
     * @param MobileLoginRequest $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function mobileLogin(MobileLoginRequest $request)
    {
        // 参数接管
        $params = $request->validated();
        // 校验验证码
        $sms = new SmsCodeModel();
        if (!$sms->check($params['mobile'], $params['code'], 'mobileLogin')) {
            return AppResult::response201($sms->getMessage());
        }

        $userModel = new UserModel();
        if ($user = $userModel->getByMobile($params['mobile'])) {
            if ($user['status'] != 1) {
                return AppResult::response201('账号被锁定，无法登录');
            }
        } else {
            if (!$userModel->register(account: $params['mobile'], mobile: $params['mobile'])) {
                return AppResult::response201('注册失败');
            }
            $user = $userModel->getData();
        }

        // 更新登录时间
        UserModel::loginTime($user['id']);

        $token = Token::create(['user_id' => $user['id']]);

        $sms->flush($params['mobile'], 'mobileLogin');// 清除已使用的短信验证码

        return AppResult::response200('登录成功！', [
            'token' => $token
        ]);
    }

    /**
     * 手机号注册
     * @param MobileRegisterRequest $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function mobileRegister(MobileRegisterRequest $request)
    {
        // 参数接管
        $params = $request->validated();

        // 校验验证码
        $sms = new SmsCodeModel();
        if (!$sms->check($params['mobile'], $params['code'], 'mobileRegister')) {
            return AppResult::response201($sms->getMessage());
        }

        $userModel = new UserModel();
        if ($userModel->getByMobile($params['mobile'])) {
            return AppResult::response201('手机号已注册！');
        }

        if (!$userModel->register(account: $params['mobile'], mobile: $params['mobile'])) {
            return AppResult::response201('注册失败');
        }
        $user = $userModel->getData();

        // 更新登录时间
        UserModel::loginTime($user['id']);

        $token = Token::create(['user_id' => $user['id']]);

        $sms->flush($params['mobile'], 'mobileRegister');// 清除已使用的短信验证码

        return AppResult::response200('注册成功！', [
            'token' => $token
        ]);
    }

    /**
     * 获取手机号
     *
     * @param LoginWxPhoneRequest $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
     */
    public function loginWxPhone(LoginWxPhoneRequest $request)
    {
        // 参数接管
        $params = $request->all();

        // 获取加密openid
        if (!empty($params['openid'])) {
            $miniUser = RedisUtil::getInstance(RedisKeyEnum::API_WECHAT_MINI_USER_OPENID, $params['openid'])->get();
            $miniUser = json_decode($miniUser ?? '', true);
            if (empty($miniUser['openid'])) {
                return AppResult::response201('操作超时，请重新登录！');
            }
        }

        // 获取手机号
        $miniApp = new MiniAppService();
        if (!$miniApp->getUserPhone($params['code'])) {
            return AppResult::response201($miniApp->getMessage() ?? '手机号授权失败', $miniApp->get());
        }

        // 获取授权结果
        $res = $miniApp->get();
        if (empty($phone = $res['phone_info']['purePhoneNumber'])) {
            return AppResult::response201('手机号授权失败');
        }

        // 校验用户账号信息
        list($exists, $user_id) = UserModel::checkExists(phone: $phone);
        if (!$exists) {
            // 手机号不存在 创建账号
            $user_id = UserModel::createAccount([
                'unionid' => $miniUser['unionid'] ?? '',
                'openid'  => $miniUser['openid'] ?? '',
                'phone'   => $phone
            ]);
            if (!$user_id) {
                return AppResult::response201('注册失败，请重试');
            }
        }

        // 更新登录时间
        UserModel::loginTime($user_id, $miniUser['openid'] ?? '', $miniUser['unionid'] ?? '');

//        $token = TokenUtil::getInstance()->getToken(['user_id' => $user_id]);
        $token = Token::create(['user_id' => $user_id]);

        return AppResult::response200('登录成功！', [
            'token' => $token
        ]);
    }

    public function thirdLogin(ThirdLoginRequest $request)
    {
        $params = $request->validated();

        $where['platform'] = $params['platform'];
        switch ($params['platform']) {
            case 'wechat_mini':
                // 获取openid
                $miniApp = new MiniAppLibrary();
                if (!$miniApp->jscode2session($params['code'])) {
                    return AppResult::response201($miniApp->getMessage() ?? '微信授权失败', $miniApp->getData());
                }
                $res = $miniApp->getData();
                if (empty($res['openid'])) {
                    return AppResult::response201('授权失败');
                }
                $where['openid'] = $res['openid'];
                $where['unionid'] = $res['unionid'];
                break;
            default:
                return AppResult::response201('暂并不支持此登录方式');
        }
        $third = new UserThirdModel();
        if (!($info = $third->getDetail(params: $where)) || empty($info['user_id'])) {
            return AppResult::response200('未绑定账号',[
                'is_bind' => 0,
                'token' => Token::create($where,600)
            ]);
        }

        // 更新登录时间
        UserModel::loginTime($info['user_id']);

        $token = Token::create(['user_id' => $info['id']]);

        return AppResult::response200('登录成功',[
            'is_bind' => 0,
            'token' => $token
        ]);
    }
}
